package com.lh0811.forge.pserv.uacs.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.pserv.basic.api.api.BizNoBaseApi;
import com.lh0811.forge.pserv.uacs.api.component.data_scope.DataScope;
import com.lh0811.forge.pserv.uacs.api.constant.UacsContant;
import com.lh0811.forge.pserv.uacs.api.param.*;
import com.lh0811.forge.pserv.uacs.api.vo.UacsDataRuleVo;
import com.lh0811.forge.pserv.uacs.api.vo.UacsPlateRoleQueryVo;
import com.lh0811.forge.pserv.uacs.api.vo.UacsTenantDepartmentPostQueryVo;
import com.lh0811.forge.pserv.uacs.server.repository.dao.*;
import com.lh0811.forge.pserv.uacs.server.repository.entity.*;
import com.lh0811.forge.pserv.uacs.server.service.TenantPostService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TenantPostServiceImpl implements TenantPostService {

    @Resource
    private UacsTenantDepartmentDao uacsTenantDepartmentDao;

    @Resource
    private BizNoBaseApi bizNoBaseApi;

    @Resource
    private UacsTenantDepartmentPostDao uacsTenantDepartmentPostDao;

    @Resource
    private UacsPlateRoleDao uacsPlateRoleDao;

    @Resource
    private UacsTenantPostRoleRefDao uacsTenantPostRoleRefDao;

    @Resource
    private UacsDataRuleDao uacsDataRuleDao;

    @Resource
    private UacsTenantPostDataRuleRefDao uacsTenantPostDataRuleRefDao;

    @Resource
    private UacsTenantPlateUserPostRefDao uacsTenantPlateUserPostRefDao;


    // 岗位创建
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tenantPostCreate(UacsTenantDepartmentPostCreateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsTenantDepartment department = uacsTenantDepartmentDao.getById(param.getDepartmentId());
        if (ObjectUtils.isEmpty(department)) {
            throw CommonException.create(ServerResponse.createByError("组织机构信息不存在"));
        }
        UacsTenantDepartmentPost uacsTenantDepartmentPost = new UacsTenantDepartmentPost();
        uacsTenantDepartmentPost.setId(IdWorker.nextId()); // 主键
        uacsTenantDepartmentPost.setTenantId(department.getTenantId()); // 租户id
        uacsTenantDepartmentPost.setTenantNo(department.getTenantNo()); // 租户no
        uacsTenantDepartmentPost.setTenantName(department.getTenantName()); // 租户名称
        uacsTenantDepartmentPost.setDepartmentId(department.getId()); // 组织机构id
        uacsTenantDepartmentPost.setDepartmentNo(department.getDepartmentNo()); // 组织机构编号
        uacsTenantDepartmentPost.setDepartmentName(department.getDepartmentName()); // 组织机构名称
        uacsTenantDepartmentPost.setPostNo(bizNoBaseApi.getNextNumByBizType(UacsContant.BizNoType.岗位编号.getBizType())); // 岗位no
        uacsTenantDepartmentPost.setPostName(param.getPostName()); // 岗位名称
        uacsTenantDepartmentPost.setActiveFlag(param.getActiveFlag()); // 是否可用
        uacsTenantDepartmentPost.setNotes(param.getNotes()); // 备注
        uacsTenantDepartmentPost.setCreateTime(new Date()); // 创建时间
        uacsTenantDepartmentPost.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
        uacsTenantDepartmentPostDao.save(uacsTenantDepartmentPost);
    }

    // 岗位删除
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tenantPostDelete(Long postId) throws Exception {
        UacsTenantDepartmentPost departmentPost = uacsTenantDepartmentPostDao.getById(postId);
        if (ObjectUtils.isEmpty(departmentPost)) {
            throw CommonException.create(ServerResponse.createByError("岗位信息不存在"));
        }
        if (BooleanUtils.isTrue(uacsTenantPlateUserPostRefDao.lambdaQuery().eq(UacsTenantPlateUserPostRef::getPostId, postId).exists())) {
            throw CommonException.create(ServerResponse.createByError("岗位已关联用户不可删除"));
        }

        // 删除岗位
        uacsTenantDepartmentPostDao.removeById(postId);

        // 删除岗位角色关联关系
        List<UacsTenantPostRoleRef> postRoleRefList = uacsTenantPostRoleRefDao.lambdaQuery().eq(UacsTenantPostRoleRef::getPostId, postId).list();
        if (CollectionUtils.isNotEmpty(postRoleRefList)) {
            uacsTenantPostRoleRefDao.removeBatchByIds(postRoleRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }

        // 删除岗位关联关系
        List<UacsTenantPostDataRuleRef> dataRuleRefList = uacsTenantPostDataRuleRefDao.lambdaQuery().eq(UacsTenantPostDataRuleRef::getPostId, postId).list();
        if (CollectionUtils.isNotEmpty(dataRuleRefList)) {
            uacsTenantPostDataRuleRefDao.removeBatchByIds(dataRuleRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }

    }


    // 岗位修改
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tenantPostUpdate(UacsTenantDepartmentPostUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsTenantDepartmentPost departmentPost = uacsTenantDepartmentPostDao.getById(param.getId());
        if (ObjectUtils.isEmpty(departmentPost)) {
            throw CommonException.create(ServerResponse.createByError("岗位信息不存在"));
        }
        // 更新信息
        UacsTenantDepartmentPost updateInfo = BeanHelper.copyBean(param, UacsTenantDepartmentPost.class);
        updateInfo.setUpdateBy(Long.valueOf(securityAuthority.getUserId()));
        updateInfo.setUpdateTime(new Date());
        // 修改组织机构
        if (ObjectUtils.isNotEmpty(param.getDepartmentId()) && !departmentPost.getDepartmentId().equals(param.getDepartmentId())) {
            UacsTenantDepartment department = uacsTenantDepartmentDao.getById(param.getDepartmentId());
            if (ObjectUtils.isEmpty(department)) {
                throw CommonException.create(ServerResponse.createByError("组织机构信息不存在"));
            }
            updateInfo.setTenantId(department.getTenantId()); // 租户id
            updateInfo.setTenantNo(department.getTenantNo()); // 租户no
            updateInfo.setTenantName(department.getTenantName()); // 租户名称
            updateInfo.setDepartmentId(department.getId()); // 组织机构id
            updateInfo.setDepartmentNo(department.getDepartmentNo()); // 组织机构编号
            updateInfo.setDepartmentName(department.getDepartmentName()); // 组织机构名称
        }
        uacsTenantDepartmentPostDao.updateById(updateInfo);


    }


    // 岗位查询(分页)
    @Override
    @DataScope
    public PageInfo<UacsTenantDepartmentPostQueryVo> tenantPostQueryPage(UacsTenantDepartmentPostQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<UacsTenantDepartmentPost> list = uacsTenantDepartmentPostDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getDepartmentId()), UacsTenantDepartmentPost::getDepartmentId, param.getDepartmentId())
                .like(StringUtils.isNotBlank(param.getPostName()), UacsTenantDepartmentPost::getPostName, param.getPostName())
                .eq(ObjectUtils.isNotEmpty(param.getActiveFlag()), UacsTenantDepartmentPost::getActiveFlag, param.getActiveFlag())
                .orderByDesc(UacsTenantDepartmentPost::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(BeanHelper.copyList(list, UacsTenantDepartmentPostQueryVo.class));
        return pageInfo;
    }

    // 岗位查询(不分页)
    @Override
    @DataScope
    public List<UacsTenantDepartmentPostQueryVo> tenantPostQueryList(UacsTenantDepartmentPostQueryListParam param) throws Exception {
        List<UacsTenantDepartmentPost> list = uacsTenantDepartmentPostDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getDepartmentId()), UacsTenantDepartmentPost::getDepartmentId, param.getDepartmentId())
                .like(StringUtils.isNotBlank(param.getPostName()), UacsTenantDepartmentPost::getPostName, param.getPostName())
                .eq(ObjectUtils.isNotEmpty(param.getActiveFlag()), UacsTenantDepartmentPost::getActiveFlag, param.getActiveFlag())
                .orderByDesc(UacsTenantDepartmentPost::getCreateTime)
                .list();
        return BeanHelper.copyList(list, UacsTenantDepartmentPostQueryVo.class);
    }

    // 岗位角色关系保存
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tenantPostRoleRefSave(UacsTenantPostRoleRefSaveParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        UacsTenantDepartmentPost departmentPost = uacsTenantDepartmentPostDao.getById(param.getPostId());
        if (ObjectUtils.isEmpty(departmentPost)) {
            throw CommonException.create(ServerResponse.createByError("岗位信息不存在"));
        }

        // 移除原来的岗位角色关联
        List<UacsTenantPostRoleRef> postRoleRefList = uacsTenantPostRoleRefDao.lambdaQuery().eq(UacsTenantPostRoleRef::getPostId, param.getPostId()).list();
        if (CollectionUtils.isNotEmpty(postRoleRefList)) {
            uacsTenantPostRoleRefDao.removeByIds(postRoleRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }

        // 创建新的关联关系
        List<UacsTenantPostRoleRef> newPostRoleRefList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(param.getRoleIdList())) {
            for (Long roleId : param.getRoleIdList()) {
                UacsPlateRole uacsPlateRole = uacsPlateRoleDao.getById(roleId);
                if (ObjectUtils.isNotEmpty(uacsPlateRole)) {
                    UacsTenantPostRoleRef postRoleRef = new UacsTenantPostRoleRef();
                    postRoleRef.setId(IdWorker.nextId()); // 主键
                    postRoleRef.setTenantId(departmentPost.getTenantId()); // 租户id
                    postRoleRef.setTenantNo(departmentPost.getTenantNo()); // 租户no
                    postRoleRef.setDepartmentId(departmentPost.getDepartmentId()); // 组织机构id
                    postRoleRef.setDepartmentNo(departmentPost.getDepartmentNo()); // 组织机构编号
                    postRoleRef.setDepartmentName(departmentPost.getDepartmentName()); // 组织机构名称
                    postRoleRef.setPostId(departmentPost.getId()); // 租户岗位id
                    postRoleRef.setRoleId(uacsPlateRole.getId()); // 应用角色id
                    postRoleRef.setNotes(""); // 备注
                    postRoleRef.setCreateTime(new Date()); // 创建时间
                    postRoleRef.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
                    newPostRoleRefList.add(postRoleRef);
                }
            }
            uacsTenantPostRoleRefDao.saveBatch(newPostRoleRefList);
        }

    }

    // 岗位数据规则保存
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void tenantPostDataRuleSave(UacsTenantPostDataRuleRefSaveParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsTenantDepartmentPost departmentPost = uacsTenantDepartmentPostDao.getById(param.getPostId());
        if (ObjectUtils.isEmpty(departmentPost)) {
            throw CommonException.create(ServerResponse.createByError("岗位信息不存在"));
        }
        // 移除原来的岗位数据规则
        List<UacsTenantPostDataRuleRef> dataRuleRefList = uacsTenantPostDataRuleRefDao.lambdaQuery().eq(UacsTenantPostDataRuleRef::getPostId, param.getPostId()).list();
        if (CollectionUtils.isNotEmpty(dataRuleRefList)) {
            uacsTenantPostDataRuleRefDao.removeByIds(dataRuleRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }

        // 保存新的规则关系
        List<UacsTenantPostDataRuleRef> uacsTenantPostDataRuleRefList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(param.getDataRuleIdList())) {
            for (Long dataRuleId : param.getDataRuleIdList()) {
                UacsDataRule uacsDataRule = uacsDataRuleDao.getById(dataRuleId);
                if (ObjectUtils.isNotEmpty(uacsDataRule)) {
                    UacsTenantPostDataRuleRef uacsTenantPostDataRuleRef = new UacsTenantPostDataRuleRef();
                    uacsTenantPostDataRuleRef.setId(IdWorker.nextId()); // 主键
                    uacsTenantPostDataRuleRef.setTenantId(departmentPost.getTenantId()); // 租户id
                    uacsTenantPostDataRuleRef.setTenantNo(departmentPost.getTenantNo()); // 租户no
                    uacsTenantPostDataRuleRef.setTenantName(departmentPost.getTenantName()); // 租户名称
                    uacsTenantPostDataRuleRef.setDepartmentId(departmentPost.getDepartmentId()); // 组织机构id
                    uacsTenantPostDataRuleRef.setDepartmentNo(departmentPost.getDepartmentNo()); // 组织机构编号
                    uacsTenantPostDataRuleRef.setDepartmentName(departmentPost.getDepartmentName()); // 组织机构名称
                    uacsTenantPostDataRuleRef.setPostId(departmentPost.getId()); // 租户岗位id
                    uacsTenantPostDataRuleRef.setPostNo(departmentPost.getPostNo()); // 租户岗位编号
                    uacsTenantPostDataRuleRef.setPostName(departmentPost.getPostName()); // 租户岗位名称
                    uacsTenantPostDataRuleRef.setDataRuleId(uacsDataRule.getId()); // 数据规则id
                    uacsTenantPostDataRuleRef.setCreateTime(new Date()); // 创建时间
                    uacsTenantPostDataRuleRef.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人

                    uacsTenantPostDataRuleRefList.add(uacsTenantPostDataRuleRef);
                }
            }
            uacsTenantPostDataRuleRefDao.saveBatch(uacsTenantPostDataRuleRefList);
        }
    }


    // 获取岗位绑定的角色列表
    @Override
    public List<UacsPlateRoleQueryVo> getPostBuildingRoleList(Long postId) throws Exception {
        List<UacsTenantPostRoleRef> roleRefList = uacsTenantPostRoleRefDao.lambdaQuery().eq(UacsTenantPostRoleRef::getPostId, postId).list();
        if (CollectionUtils.isEmpty(roleRefList)) {
            return Lists.newArrayList();
        }
        List<UacsPlateRole> roleList = uacsPlateRoleDao.listByIds(roleRefList.stream().map(ele -> ele.getRoleId()).collect(Collectors.toList()));
        return BeanHelper.copyList(roleList, UacsPlateRoleQueryVo.class);
    }


    // 获取岗位绑定的数据规则列表
    @Override
    public List<UacsDataRuleVo> getPostBuildingDataRuleList(Long postId) throws Exception {
        List<UacsTenantPostDataRuleRef> dataRuleRefList = uacsTenantPostDataRuleRefDao.lambdaQuery().eq(UacsTenantPostDataRuleRef::getPostId, postId).list();
        if (CollectionUtils.isEmpty(dataRuleRefList)) {
            return Lists.newArrayList();
        }
        List<UacsDataRule> dataRuleList = uacsDataRuleDao.listByIds(dataRuleRefList.stream().map(ele -> ele.getDataRuleId()).collect(Collectors.toList()));
        return BeanHelper.copyList(dataRuleList, UacsDataRuleVo.class);
    }

}
